<?php

namespace tmcore\services\wechat;

use EasyWeChat\Kernel\Exceptions\InvalidArgumentException;
use EasyWeChat\OfficialAccount\Application;
use tmcore\exceptions\WeChatException;

/**
 * 微信公众号服务类
 */
class WxOaService
{
    protected Application $app;

    protected array $config;

    /**
     * 初始化
     */
    public function __construct()
    {
        $this->config = $this->getConfig();
        $this->app = new Application($this->config);
    }

    /**
     * 获取实例
     * @return Application
     */
    public function getApplication() {
        return $this->app;
    }

    /**
     * 获取配置
     * @return array
     * @throws WeChatException
     */
    protected function getConfig()
    {
        $config = WxConfigService::getOaConfig();
        if (empty($config['app_id']) || empty($config['secret'])) {
            throw new WeChatException('请先设置微信公众号配置');
        }
        return $config;
    }

    /**
     * 获取服务端
     * @return \EasyWeChat\Kernel\Contracts\Server|\EasyWeChat\OfficialAccount\Server
     * @throws \EasyWeChat\Kernel\Exceptions\InvalidArgumentException
     * @throws \ReflectionException
     * @throws \Throwable
     */
    public function getServer()
    {
        return $this->app->getServer();
    }

    /**
     * 根据code获取微信信息
     * @param string $code
     * @return array
     * @throws WeChatException|\EasyWeChat\Kernel\Exceptions\InvalidArgumentException
     */
    public function getOaInfoByCode($code)
    {
        $response = $this->app->getOAuth()
            ->scopes(['snsapi_userinfo'])
            ->userFromCode($code)
            ->getRaw();

        if (!isset($response['openid']) || empty($response['openid'])) {
            throw new WeChatException('获取openID失败');
        }

        return $response;
    }

    /**
     * 获取公众号授权跳转路径
     * @param string $url
     * @return string
     * @throws InvalidArgumentException
     */
    public function getCodeUrl($url)
    {
        return $this->app->getOAuth()
            ->scopes(['snsapi_userinfo'])
            ->redirect($url);
    }

    /**
     * 获取jssdk配置
     * @param $url
     * @param $jsApiList
     * @param array $openTagList
     * @param bool $debug
     * @return array|string
     * @throws \EasyWeChat\Kernel\Exceptions\InvalidArgumentException
     * @throws \EasyWeChat\Kernel\Exceptions\InvalidConfigException
     * @throws \EasyWeChat\Kernel\Exceptions\RuntimeException
     * @throws \GuzzleHttp\Exception\GuzzleException
     * @throws \Psr\SimpleCache\InvalidArgumentException
     */
    public function getJsConfig($url, $jsApiList, $openTagList = [], $debug = false)
    {
        return $this->app->getUtils()->buildJsSdkConfig($url, $jsApiList, $openTagList, $debug);
    }

    /**
     * 获取用户信息
     * @param string|array $openid
     * @return array|mixed[]
     * @throws WeChatException
     */
    public function getUserInfo($openid)
    {
        try {
            if (is_array($openid)) {
                $response = $this->app->getClient()->postJson('/cgi-bin/user/info/batchget',[
                    'openid' => $openid
                ]);
                $result = $response->toArray(false);
                $this->checkResult($result);
                return $result['user_info_list'];

            } else {
                $response = $this->app->getClient()->get('/cgi-bin/user/info',[
                    'openid' => $openid
                ]);
                $result = $response->toArray(false);
                $this->checkResult($result);
                return $result;
            }
        } catch (\Throwable $e) {
            throw new WeChatException($e->getMessage());
        }
    }

    /**
     * 抛出微信异常
     * @param $result
     * @return void
     * @throws WeChatException
     */
    public function checkResult($result)
    {
        if (!empty($result['code']) && !empty($result['message'])) {
            throw new WeChatException('微信:'. $result['code'] . '-' . $result['message']);
        }
        if (!empty($result['errcode']) && !empty($result['errmsg'])) {
            throw new WeChatException('微信:'. $result['errcode'] . '-' . $result['errmsg']);
        }
    }
}